// 自封装map
class MemoizeMap {
  constructor() {
    this._map = new Map()
    this._weakMap = new WeakMap()
  }
  _isObject(key) {
    return typeof key === 'object' && key !== null
  }
  get(key) {
    if (this._isObject(key)) {
      return this._weakMap.get(key)
    } else {
      return this._map.get(key)
    }
  }
  set(key, value) {
    if (this._isObject(key)) {
      return this._weakMap.set(key, value)
    } else {
      return this._map.set(key, value)
    }
  }
  has(key) {
    if (this._isObject(key)) {
      return this._weakMap.has(key)
    } else {
      return this._map.has(key)
    }
  }
}
function memoize(fn, resolver) {
  if (typeof resolver !== 'function') {
    resolver = (key) => key
  }
  function memoized(...args) {
    const key = resolver(...args)
    if (memoized.cache.has(key)) {
      return memoized.cache.get(key)
    }
    const result = fn.apply(this, args)
    memoized.cache.set(key, result)
    return result
  }

  memoized.cache = new MemoizeMap()

  return memoized
}

var object = { a: 1, b: 2 }
var other = { c: 3, d: 4 }

var values = memoize((obj) => Object.values(obj))
console.log(values(object)) // [1, 2]
console.log(values(other)) // [3, 4]
object.a = 2
console.log(values(object)) // [1, 2]
// 更新缓存
values.cache.set(object, ['a', 'b'])
console.log(values(object)) // ['a', 'b']
